/**
 * $Revision: 1.1 $
 * $Date: 2010/06/28 07:02:38 $
 *
 * Copyright (C) 2006 Jive Software. All rights reserved.
 *
 * This software is published under the terms of the GNU Lesser Public License (LGPL),
 * a copy of which is included in this distribution.
 */

package cn.newgrand.netcall.consultant.ui;

import org.jivesoftware.resource.Res;
import org.jivesoftware.resource.SparkRes;
import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smackx.packet.VCard;
import org.jivesoftware.spark.PluginManager;
import org.jivesoftware.spark.SparkManager;
import org.jivesoftware.spark.util.GraphicUtils;
import org.jivesoftware.spark.util.ModelUtil;
import org.jivesoftware.spark.util.log.Log;
import org.jivesoftware.sparkimpl.plugin.gateways.transports.Transport;
import org.jivesoftware.sparkimpl.plugin.gateways.transports.TransportUtils;

import cn.newgrand.netcall.consultant.ConsultantPlugin;
import cn.newgrand.netcall.consultant.SpecialistVCardManager;
import cn.newgrand.smackx.consultant.ConsultantManager;
import cn.newgrand.smackx.consultant.packet.SpecialistVCard;

import javax.swing.*;

import java.awt.*;
import java.awt.event.MouseEvent;
import java.net.MalformedURLException;
import java.net.URL;

/**
 * Represents the UI for the "ToolTip" functionallity in the ContactList.
 *
 * @author Derek DeMoro
 */
public class SpecialistInfoWindow extends JPanel {
    private final JLabel nicknameLabel = new JLabel();
    private final JTextArea statusLabel = new JTextArea();
    private final JLabel fullJIDLabel = new JLabel();
    private final JLabel avatarLabel = new JLabel();
    private final JLabel iconLabel = new JLabel();
    private final JLabel titleLabel = new JLabel();
    private final JLabel avatarBorderLabel=new JLabel();
    private final JLabel specialtyLable = new JLabel();

    private SpecialistItem specialistItem;

    private JWindow window = new JWindow();

    private static SpecialistInfoWindow singleton;
    private static final Object LOCK = new Object();

    /**
     * Returns the singleton instance of <CODE>ContactInfoWindow</CODE>,
     * creating it if necessary.
     * <p/>
     *
     * @return the singleton instance of <Code>ContactInfoWindow</CODE>
     */
    public static SpecialistInfoWindow getInstance() {
        // Synchronize on LOCK to ensure that we don't end up creating
        // two singletons.
        synchronized (LOCK) {
            if (null == singleton) {
                SpecialistInfoWindow controller = new SpecialistInfoWindow();
                singleton = controller;
                return controller;
            }
        }
        return singleton;
    }

    private SpecialistInfoWindow() {
   	 
        setLayout(new GridBagLayout());
        
      
        setBackground(Color.white);
        add(avatarBorderLabel, new GridBagConstraints(0, 1, 1, 3, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(10, 10, 15, 15), 0, 0));
        add(avatarLabel, new GridBagConstraints(0, 1, 1, 3, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(15, 15, 15, 15), 0, 0));
        add(nicknameLabel, new GridBagConstraints(2, 1, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(15, 5, 5, 5), 0, 0));
        add(iconLabel, new GridBagConstraints(2, 2, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
        add(statusLabel, new GridBagConstraints(2, 2, 1, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 23, 5, 5), 0, 0));
        //add(titleLabel, new GridBagConstraints(0, 3, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 5, 5, 5), 0, 0));
        add(specialtyLable, new GridBagConstraints(2, 3, 1, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 5, 5, 5), 0, 0));
        add(fullJIDLabel, new GridBagConstraints(0, 5, 4, 1, 1.0, 1.0, GridBagConstraints.SOUTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));

        avatarBorderLabel.setIcon(SparkRes.getImageIcon(SparkRes.AVATAR_BORDER));
        nicknameLabel.setFont(new Font("Dialog", Font.BOLD, 12));
        specialtyLable.setFont(new Font("Dialog", Font.PLAIN, 12));
        statusLabel.setFont(new Font("Dialog", Font.PLAIN, 12));
        statusLabel.setForeground(Color.gray);
        statusLabel.setLineWrap(true);
        statusLabel.setWrapStyleWord(true);
        statusLabel.setEditable(false);
        statusLabel.setBorder(null);
        fullJIDLabel.setFont(new Font("Dialog", Font.PLAIN, 12));
        //TODO
        fullJIDLabel.setOpaque(true);
        fullJIDLabel.setBackground(new Color(251,198,96));
//        fullJIDLabel.setForeground(Color.gray);
        titleLabel.setFont(new Font("Dialog", Font.PLAIN, 12));
//        titleLabel.setForeground(Color.gray);


//        fullJIDLabel.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, Color.gray));
        //TODO 设置边框及背景色
//        setBorder(BorderFactory.createLineBorder(Color.gray, 1));
        fullJIDLabel.setBackground(new Color(251,241,223));
        setBorder(BorderFactory.createLineBorder(new Color(251,198,97)));
        fullJIDLabel.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, new Color(251,198,97)));

        window.getContentPane().add(this);
        
        SpecialistList specialistList = ((ConsultantPlugin)PluginManager.getInstance().getPlugin(ConsultantPlugin.class)).getSpecialistList();
        specialistList.addContactListListener(new SpecialistListListener() {
            public void contactItemAdded(SpecialistItem item) {
            }

            public void contactItemRemoved(SpecialistItem item) {
            }

            public void contactGroupAdded(SpecialistGroup group) {
            }

            public void contactGroupRemoved(SpecialistGroup group) {
            }

            public void contactItemClicked(SpecialistItem item) {
                if (window != null) {
                    window.dispose();
                }
            }

            public void contactItemDoubleClicked(SpecialistItem item) {
                if (window != null) {
                    window.dispose();
                }
            }
        });
    }

    public void display(SpecialistGroup group, MouseEvent e) {
        int loc = group.getList().locationToIndex(e.getPoint());


        SpecialistItem item = (SpecialistItem)group.getList().getModel().getElementAt(loc);
        if (item == null || item.getJID() == null) {
            return;
        }

        if (getContactItem() != null && getContactItem() == item) {
            return;
        }
        iconLabel.setIcon(item.getIcon());

        Point point = group.getList().indexToLocation(loc);

        window.setFocusableWindowState(false);
        setContactItem(item);
        window.pack();


        Point mainWindowLocation = SparkManager.getMainWindow().getLocationOnScreen();
        Point listLocation = group.getList().getLocationOnScreen();

        int x = (int)mainWindowLocation.getX() + SparkManager.getMainWindow().getWidth();

        final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        if ((int)screenSize.getWidth() - getPreferredSize().getWidth() >= x) {
            int y = (int)listLocation.getY() + (int)point.getY();
            y = y - 5;
            window.setLocation(x, y);
            if (!window.isVisible()) {
                window.setVisible(true);
            }
        }
        else {
            int y = (int)listLocation.getY() + (int)point.getY();
            y = y - 5;
            window.setLocation((int)mainWindowLocation.getX() - (int)getPreferredSize().getWidth(), y);
            if (!window.isVisible()) {
                window.setVisible(true);
            }
        }
    }

    public void setContactItem(SpecialistItem specialistItem) {
        this.specialistItem = specialistItem;
        if (specialistItem == null) {
            return;
        }

        nicknameLabel.setText(specialistItem.getTipDisplayName());

        String status = specialistItem.getStatus();
        if (!ModelUtil.hasLength(status)) {
            if (specialistItem.getPresence() == null || !specialistItem.getPresence().isAvailable()) {
                status = Res.getString("offline");
            }
            else {
                status = Res.getString("online");
            }
        }
        statusLabel.setText(status);

        Transport transport = TransportUtils.getTransport(StringUtils.parseServer(specialistItem.getJID()));
        if (transport != null) {
            fullJIDLabel.setIcon(transport.getIcon());
            String name = StringUtils.parseName(specialistItem.getJID());
            name = StringUtils.unescapeNode(name);
            fullJIDLabel.setText(transport.getName() + " - " + name);
        }
        else {
        	//TODO
            String name = StringUtils.unescapeNode(specialistItem.getJID());
            fullJIDLabel.setText("    "+name);
            fullJIDLabel.setIcon(null);
        }
        avatarLabel.setBorder(null);

        try {
            URL avatarURL = specialistItem.getAvatarURL();
            ImageIcon icon = null;
            if (avatarURL != null) {
                icon = new ImageIcon(avatarURL);
            }

            if (icon != null && icon.getIconHeight() > 1) {
//                icon = GraphicUtils.scaleImageIcon(icon, 96, 96);
            	icon = GraphicUtils.scale(icon, 50, 50);
            	avatarLabel.setIcon(icon);
            }
            else {
                icon = GraphicUtils.scale(SparkRes.getImageIcon(SparkRes.DEFAULT_AVATAR_64x64_IMAGE),50,50);
                avatarLabel.setIcon(icon);
            }
//            avatarLabel.setBorder(BorderFactory.createBevelBorder(0, Color.white, Color.lightGray));
        }
        catch (MalformedURLException e) {
            Log.error(e);
        }

        // Get VCard from memory (if available)
        String title = "";
        VCard vcard = SparkManager.getVCardManager().getVCardFromMemory(StringUtils.parseBareAddress(specialistItem.getJID()));
        if (vcard != null) {
            title = vcard.getField("TITLE");
            if (!ModelUtil.hasLength(title)) {
                title = "";
            }
        }
        titleLabel.setText(title);
        //显示窗口增加特长信息
        String spid = specialistItem.getAlias();
        SpecialistVCard specialistVCard = null;
        if(SpecialistVCardManager.getInstance().isExistSpecialistVCard(spid)){
        	specialistVCard = SpecialistVCardManager.getInstance().getSpecialistVCard(spid);
    	}else{
    		specialistVCard = ConsultantManager.getInstance(SparkManager.getConnection()).getSpecialistVCard(spid);
    		SpecialistVCardManager.getInstance().addSecialistVCard(spid, specialistVCard);
    	}
        String specialty = specialistVCard.getFieldValue("specialty");
        if(specialty == null || "".equals(specialty)){
        	specialty = "暂无";
        }

        specialtyLable.setText("特长："+specialty);
    }

    public SpecialistItem getContactItem() {
        return specialistItem;
    }

    public void dispose() {
        window.setVisible(false);
        specialistItem = null;
        window.dispose();
    }


    public Dimension getPreferredSize() {
        final Dimension size = super.getPreferredSize();
        size.width = 300;
        size.height = 125;
        return size;
    }

    public void mouseEntered(MouseEvent e) {
    }

    public void mouseExited(MouseEvent e) {
        Point point = e.getPoint();

        Dimension dim = window.getSize();

        int x = (int)point.getX();
        int y = (int)point.getY();

        boolean close = false;

        if (x < 0 || x >= dim.getWidth()) {
            close = true;
        }

        if (y < 0 || y >= dim.getHeight()) {
            close = true;
        }

        if (close) {
            window.setVisible(false);
            specialistItem = null;
        }
    }

}
